package com.songlanyun.common.utils.custom;

import java.math.BigDecimal;

/**
 * 数字计算常用方法
 */
public class MathUtils
{

    /**
     * 判断一个非负整数是否是2的幂
     *
     * @param num
     * @return boolean
     */
    public static boolean isPowerOf2(int num) {
        if (num <= 0) return false;
        return ((num & (num - 1)) == 0);
    }

    /**
     * 判断一个数是否在容器数中存在（2的幂位按位与）
     *
     * @param num
     * @param iocValue
     * @return bool
     */
    public static boolean andOperation(int num, int iocValue) {
        if (!MathUtils.isPowerOf2(num)) return false;
        if (num > iocValue) return false;
        int result = num & iocValue;
        if (result > 0) return true;
        return false;
    }


    public static BigDecimal setScale(Double value) {
        return (new BigDecimal(value)).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal setScale(Double value,int newScale) {
        return (new BigDecimal(value)).setScale(newScale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal setScaleDown(Double value) {
        return (new BigDecimal(value)).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal setScaleDown(Double value,int newScale) {
        return (new BigDecimal(value)).setScale(newScale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 两个高精度数相减
     */
    public static BigDecimal subtract(BigDecimal val1, BigDecimal val2) {
        return val1.subtract(val2).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 高精度数相减
     */
    public static BigDecimal subtractMulti(BigDecimal... values) {
        BigDecimal result = values[0];
        for (int len = 1; len < values.length; len++) {
            result = subtract(result, values[len]);
        }
        return result;
    }

    /**
     * 两个高精度数相加
     */
    public static BigDecimal add(BigDecimal val1, BigDecimal val2) {
        return val1.add(val2).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 两个高精度数相加
     */
    public static BigDecimal addMulti(BigDecimal... values) {
        BigDecimal result = values[0];
        for (int len = 1; len < values.length; len++) {
            result = add(result, values[len]);
        }
        return result;
    }


    /**
     * 两个高精度数相乘
     */
    public static BigDecimal multiply(BigDecimal val1, BigDecimal val2) {

        return multiply(val1, val2, 2);
    }


    /**
     * 两个高精度数相乘
     */
    public static BigDecimal multiplyMulti(int scale,BigDecimal... values) {

        double result = values[0].doubleValue();
        for (int len = 1; len < values.length; len++) {
            result = result * values[len].doubleValue();
        }
        return BigDecimal.valueOf(result).setScale(scale,BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 两个高精度数相乘
     */
    public static BigDecimal multiply(BigDecimal val1, BigDecimal val2, int scale) {

        return val1.multiply(val2).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }



    /**
     * 两个高精度数相除
     */
    public static BigDecimal divide(BigDecimal val1, BigDecimal val2) {
        return divide(val1, val2, 2);
    }

    /**
     * 两个高精度数相除
     */
    public static BigDecimal divide(BigDecimal val1, BigDecimal val2, int scale) {
        return val1.divide(val2).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 两个高精度数相除
     */
    public static BigDecimal divideMulti(int scale,BigDecimal... values) {

        double result = values[0].doubleValue();
        for (int len = 1; len < values.length; len++) {
            result = result / values[len].doubleValue();
        }
        return BigDecimal.valueOf(result).setScale(scale,BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算倍数
     */
    public static int multiple(BigDecimal val1, BigDecimal val2) {
        return val1.divide(val2, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_DOWN).intValue();
    }


}
